/*
 *  Created at 2012-04-10 14:11 GMT-03:00
 *  Author: Victor Williams Stafusa da Silva
 *  JSmartUnit
 */
package org.jsmartunit.test.tools;

import java.util.ArrayList;
import java.util.List;

import org.junit.Ignore;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;

/**
 * @author Victor Williams Stafusa da Silva
 */
@Ignore
public final class Event {

    private static final class BadThrowable extends Throwable {
        private static final long serialVersionUID = 1962299513112303564L;
        private BadThrowable() {}
    }

    private final EventType type;
    private final String description;
    private final Class<? extends Throwable> failureType;

    public Event(EventType type, String description, Class<? extends Throwable> failureType) {
        this.type = type;
        this.description = description;
        this.failureType = failureType;
    }

    public EventType getType() {
        return type;
    }

    public String getDescription() {
        return description;
    }

    public Class<? extends Throwable> getFailureType() {
        return failureType;
    }

    @Override
    public String toString() {
        return "{" + type + " - (" + description + ")" + (failureType == null ? "" : failureType.getSimpleName()) + "}";
    }

    public static Event forType(EventType type) {
        return new Event(type, "<" + type.name() + ">", null);
    }

    public static Event forType(EventType type, Failure failure) {
        return new Event(type, failure.getDescription().getDisplayName(), failure.getException().getClass());
    }

    public static Event forType(EventType type, Description description) {
        return new Event(type, description.getDisplayName(), null);
    }

    public static Event forType(EventType type, String description) {
        return new Event(type, description, null);
    }

    public static Event getNull() {
        return new Event(null, "<null>", null);
    }

    public static Event getBad() {
        return new Event(EventType.BAD_EVENT, "<bad>", BadThrowable.class);
    }

    public static Event forClass(EventType type, Class<?> testClass, String description, Class<? extends Throwable> failureType) {
        return new Event(type, description == null ? testClass.getName() : description, failureType);
    }

    public static Event forClass(EventType type, Class<?> testClass) {
        return new Event(type, testClass.getName(), null);
    }

    public static Event forClass(EventType type, Class<?> testClass, String description) {
        return new Event(type, description == null ? testClass.getName() : description + "(" + testClass.getName() + ")", null);
    }

    public static Event forClass(EventType type, Class<?> testClass, Class<? extends Throwable> failureType) {
        return new Event(type, testClass.getName(), failureType);
    }

    public static List<Event> fromMessages(String... messages) {
        List<Event> events = new ArrayList<Event>(messages.length);
        for (String message : messages) {
            events.add(forType(EventType.MESSAGE, message));
        }
        return events;
    }
}
